home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
- The Netherlands.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute this software and its
- documentation for any purpose and without fee is hereby granted,
- provided that the above copyright notice appear in all copies and that
- both that copyright notice and this permission notice appear in
- supporting documentation, and that the names of Stichting Mathematisch
- Centrum or CWI or Corporation for National Research Initiatives or
- CNRI not be used in advertising or publicity pertaining to
- distribution of the software without specific, written prior
- permission.
-
- While CWI is the initial source for this software, a modified version
- is made available by the Corporation for National Research Initiatives
- (CNRI) at the Internet address ftp://ftp.python.org.
-
- STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
- REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
- CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- PERFORMANCE OF THIS SOFTWARE.
-
- ******************************************************************/
-
- /* Traceback implementation */
-
- #include "allobjects.h"
-
- #include "sysmodule.h"
- #include "compile.h"
- #include "frameobject.h"
- #include "traceback.h"
- #include "structmember.h"
- #include "osdefs.h"
-
- typedef struct _tracebackobject {
- OB_HEAD
- struct _tracebackobject *tb_next;
- frameobject *tb_frame;
- int tb_lasti;
- int tb_lineno;
- } tracebackobject;
-
- #include "protos/traceback_protos.h"
-
- #define OFF(x) offsetof(tracebackobject, x)
-
- static struct memberlist tb_memberlist[] = {
- {"tb_next", T_OBJECT, OFF(tb_next)},
- {"tb_frame", T_OBJECT, OFF(tb_frame)},
- {"tb_lasti", T_INT, OFF(tb_lasti)},
- {"tb_lineno", T_INT, OFF(tb_lineno)},
- {NULL} /* Sentinel */
- };
-
- static object *
- tb_getattr(tb, name)
- tracebackobject *tb;
- char *name;
- {
- return getmember((char *)tb, tb_memberlist, name);
- }
-
- static void
- tb_dealloc(tb)
- tracebackobject *tb;
- {
- XDECREF(tb->tb_next);
- XDECREF(tb->tb_frame);
- DEL(tb);
- }
-
- #define Tracebacktype PyTraceBack_Type
- #define is_tracebackobject PyTraceBack_Check
-
- typeobject Tracebacktype = {
- OB_HEAD_INIT(&Typetype)
- 0,
- "traceback",
- sizeof(tracebackobject),
- 0,
- (destructor)tb_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)tb_getattr, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- };
-
- static tracebackobject *
- newtracebackobject(next, frame, lasti, lineno)
- tracebackobject *next;
- frameobject *frame;
- int lasti, lineno;
- {
- tracebackobject *tb;
- if ((next != NULL && !is_tracebackobject(next)) ||
- frame == NULL || !is_frameobject(frame)) {
- err_badcall();
- return NULL;
- }
- tb = NEWOBJ(tracebackobject, &Tracebacktype);
- if (tb != NULL) {
- XINCREF(next);
- tb->tb_next = next;
- XINCREF(frame);
- tb->tb_frame = frame;
- tb->tb_lasti = lasti;
- tb->tb_lineno = lineno;
- }
- return tb;
- }
-
- static tracebackobject *tb_current = NULL;
-
- int
- tb_here(frame)
- frameobject *frame;
- {
- tracebackobject *tb;
- tb = newtracebackobject(tb_current, frame, frame->f_lasti, frame->f_lineno);
- if (tb == NULL)
- return -1;
- XDECREF(tb_current);
- tb_current = tb;
- return 0;
- }
-
- object *
- tb_fetch()
- {
- object *v;
- v = (object *)tb_current;
- tb_current = NULL;
- return v;
- }
-
- int
- tb_store(v)
- object *v;
- {
- if (v != NULL && !is_tracebackobject(v)) {
- err_badcall();
- return -1;
- }
- XDECREF(tb_current);
- XINCREF(v);
- tb_current = (tracebackobject *)v;
- return 0;
- }
-
- static void
- tb_displayline(f, filename, lineno, name)
- object *f;
- char *filename;
- int lineno;
- char *name;
- {
- FILE *xfp;
- char linebuf[1000];
- int i;
- #ifdef MPW
- /* This is needed by MPW's File and Line commands */
- #define FMT " File \"%.900s\"; line %d # in %s\n"
- #else
- /* This is needed by Emacs' compile command */
- #define FMT " File \"%.900s\", line %d, in %s\n"
- #endif
- xfp = fopen(filename, "r");
- if (xfp == NULL) {
- /* Search tail of filename in sys.path before giving up */
- object *path;
- char *tail = strrchr(filename, SEP);
- if (tail == NULL)
- tail = filename;
- else
- tail++;
- path = sysget("path");
- if (path != NULL && is_listobject(path)) {
- int npath = getlistsize(path);
- int taillen = strlen(tail);
- char namebuf[MAXPATHLEN+1];
- for (i = 0; i < npath; i++) {
- object *v = getlistitem(path, i);
- if (is_stringobject(v)) {
- int len;
- len = getstringsize(v);
- if (len + 1 + taillen >= MAXPATHLEN)
- continue; /* Too long */
- strcpy(namebuf, getstringvalue(v));
- if (strlen(namebuf) != len)
- continue; /* v contains '\0' */
- if (len > 0 && namebuf[len-1] != SEP)
- namebuf[len++] = SEP;
- strcpy(namebuf+len, tail);
- xfp = fopen(namebuf, "r");
- if (xfp != NULL) {
- filename = namebuf;
- break;
- }
- }
- }
- }
- }
- sprintf(linebuf, FMT, filename, lineno, name);
- writestring(linebuf, f);
- if (xfp == NULL)
- return;
- for (i = 0; i < lineno; i++) {
- if (fgets(linebuf, sizeof linebuf, xfp) == NULL)
- break;
- }
- if (i == lineno) {
- char *p = linebuf;
- while (*p == ' ' || *p == '\t' || *p == '\014')
- p++;
- writestring(" ", f);
- writestring(p, f);
- if (strchr(p, '\n') == NULL)
- writestring("\n", f);
- }
- fclose(xfp);
- }
-
- static void
- tb_printinternal(tb, f, limit)
- tracebackobject *tb;
- object *f;
- int limit;
- {
- int depth = 0;
- tracebackobject *tb1 = tb;
- while (tb1 != NULL) {
- depth++;
- tb1 = tb1->tb_next;
- }
- while (tb != NULL && !intrcheck()) {
- if (depth <= limit)
- tb_displayline(f,
- getstringvalue(tb->tb_frame->f_code->co_filename),
- tb->tb_lineno,
- getstringvalue(tb->tb_frame->f_code->co_name));
- depth--;
- tb = tb->tb_next;
- }
- }
-
- int
- tb_print(v, f)
- object *v;
- object *f;
- {
- object *limitv;
- int limit = 1000;
- if (v == NULL)
- return 0;
- if (!is_tracebackobject(v)) {
- err_badcall();
- return -1;
- }
- limitv = sysget("tracebacklimit");
- if (limitv && is_intobject(limitv)) {
- limit = getintvalue(limitv);
- if (limit <= 0)
- return 0;
- }
- writestring("Traceback (innermost last):\n", f);
- tb_printinternal((tracebackobject *)v, f, limit);
- return 0;
- }
-